<template>
    <n-tooltip>
        <template #trigger>
            <el-button @click="pickLocation" type="primary">
                <n-icon>
                    <i class="fa fa-crosshairs" />
                </n-icon>
            </el-button>
        </template>
        定位
    </n-tooltip>

    <el-dialog v-model="showPicker" title="选择位置" style="width: 650px">
        <div class="cs-picker" ref="pickerRef" />
        <template #footer>
            <n-space justify="end">
                <el-button type="primary" @click="() => (showPicker = false)"
                    >保存</el-button
                >
            </n-space>
        </template>
    </el-dialog>
</template>

<script setup lang="ts">
import { nextTick, ref, watch, toRefs } from 'vue'
import { NSpace, NIcon, NTooltip } from 'naive-ui'
import iconList from '@/common/IconList'
import lodash from 'lodash'
import { ElMessage } from 'element-plus'
import { IMouseMoveEvent, IMovement } from '@/types/utils'

type IPos = number[]

// const props = defineProps({
//     loc: {
//         required: true,
//         type: Array as PropType<IPos>,
//         default: () => [0, 0, 0],
//     },
// })
const props = withDefaults(defineProps<{ loc: IPos }>(), {
    loc: () => [0, 0, 0],
})

const { loc } = toRefs(props)

const emits = defineEmits(['update:loc'])

Cesium.Ion.defaultAccessToken =
    // 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI0NjBlYzRiYS0wMDRhLTRjZWYtODJhOS1jZTk5ZmI4ZDg5ZTIiLCJpZCI6ODI1MCwic2NvcGVzIjpbImFzciIsImdjIl0sImlhdCI6MTU1MTU3MDU1Mn0.yfJ_i4EPiunFj_qUftuv1ksx4pUNgnPC16vQCBGrM08'
    'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJhZTJkMzA0NS1mZjg2LTRkZjUtYjFjMi00ZWViOWVhNjdkZTUiLCJpZCI6NzU4MzEsImlhdCI6MTYzODkyOTMxMH0.G8NRwYdB5stq4MHuGtPOuRAEcrGxxkNNJJEtELCaRWs'
const pickerRef = ref<HTMLDivElement>()

const showPicker = ref(false)
const pickLocation = () => {
    showPicker.value = true
}

let viewer: Cesium.Viewer
let pinBuilder = new Cesium.PinBuilder()

const pin_id = 'pin_mark'

const buildMarker = (loc: IPos) => {
    if (loc.length < 3) return
    viewer.entities.removeById(pin_id)

    Promise.resolve(
        pinBuilder.fromUrl(
            // entity.icon,
            iconList.Crosshair,
            Cesium.Color.ROYALBLUE,
            48,
        ),
    )
        .then((canvas) => {
            viewer.entities.add({
                id: pin_id,
                position: Cesium.Cartesian3.fromDegrees(
                    loc[0],
                    loc[1],
                    loc[2] || 0,
                ),
                billboard: {
                    image: canvas.toDataURL(),
                    verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                    color: Cesium.Color.WHITE,
                    scale: 0.83,
                },
                label: {
                    //填充色
                    fillColor: Cesium.Color.WHITE,
                    //字体
                    font: 'bold 8pt Segoe UI Semibold',
                    // // 水平原点
                    horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
                    text: `经度：${loc[0]},纬度${loc[1]}`,
                    outlineColor: Cesium.Color.BLACK,
                    outlineWidth: 3,
                    pixelOffset: new Cesium.Cartesian2(0, -65),
                    style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                    verticalOrigin: Cesium.VerticalOrigin.TOP,
                    eyeOffset: new Cesium.Cartesian3(0, 0, -100000),
                },
            })
        })
        .catch((e) => {
            ElMessage.warning('图标加载错误，请重新点击', e)
        })
}

watch(showPicker, () => {
    if (showPicker.value) {
        nextTick(async () => {
            viewer = new Cesium.Viewer(pickerRef.value!, {
                geocoder: false,
                selectionIndicator: false,
                homeButton: false,
                sceneModePicker: false,
                navigationHelpButton: false,
                fullscreenButton: false,
                navigationInstructionsInitiallyVisible: false,
                timeline: false,
                baseLayerPicker: false,
                animation: false,
                imageryProvider: new Cesium.TileMapServiceImageryProvider({
                    url: Cesium.buildModuleUrl(
                        'Assets/Textures/NaturalEarthII',
                    ),
                }),
            })

            buildMarker(loc.value)

            viewer.camera.flyTo({
                destination: Cesium.Cartesian3.fromDegrees(
                    loc.value[0] || 0,
                    loc.value[1] || 0,
                    10000000,
                ),
                duration: 0.8,
            })

            const tileLayer = new Cesium.UrlTemplateImageryProvider({
                url: '/tiles/img_c/{oz}/{x}/{y}',
                // url: '/tiles/img_c/{oz}/{x}/{y}.png',
                customTags: {
                    oz(
                        imageProvider: any,
                        x: number,
                        y: number,
                        level: number,
                    ) {
                        return level + 1
                    },
                },
                tileHeight: 256,
                tileWidth: 256,
                tilingScheme: new Cesium.GeographicTilingScheme({}),
            })
            viewer.imageryLayers.addImageryProvider(tileLayer)

            // const labelLayer = new Cesium.UrlTemplateImageryProvider({
            //     url: '/tiles/label/{oz}/{x}/{y}',
            //     customTags: {
            //         oz(
            //             imageProvider: any,
            //             x: number,
            //             y: number,
            //             level: number,
            //         ) {
            //             return level + 1
            //         },
            //     },
            //     tileHeight: 256,
            //     tileWidth: 256,
            //     tilingScheme: new Cesium.GeographicTilingScheme({}),
            // })
            // viewer.imageryLayers.addImageryProvider(labelLayer)

            const scene = viewer.scene
            if (!scene.pickPositionSupported) {
                window.alert('This browser does not support pickPosition.')
            }
            const entity = viewer.entities.add({
                label: {
                    show: false,
                    showBackground: true,
                    font: '14px monospace',
                    horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
                    verticalOrigin: Cesium.VerticalOrigin.TOP,
                    pixelOffset: new Cesium.Cartesian2(15, 0),
                },
            })

            let handler
            handler = new Cesium.ScreenSpaceEventHandler(scene.canvas)
            handler.setInputAction(function (movement: IMouseMoveEvent) {
                const cartesian = viewer.camera.pickEllipsoid(
                    movement.endPosition,
                    scene.globe.ellipsoid,
                )
                if (cartesian) {
                    const cartographic =
                        Cesium.Cartographic.fromCartesian(cartesian)
                    const longitudeString = Cesium.Math.toDegrees(
                        cartographic.longitude,
                    ).toFixed(2)
                    const latitudeString = Cesium.Math.toDegrees(
                        cartographic.latitude,
                    ).toFixed(2)

                    entity.position = new Cesium.ConstantPositionProperty(
                        cartesian,
                    )
                    entity.label!.show = new Cesium.SampledProperty(true)
                    entity.label!.text = new Cesium.SampledProperty(
                        `Lon: ${`   ${longitudeString}`.slice(-7)}\u00B0` +
                            `\nLat: ${`   ${latitudeString}`.slice(
                                -7,
                            )}\u00B0 双击选择坐标`,
                    )
                } else {
                    entity.label!.show = new Cesium.SampledProperty(false)
                }
            }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
            handler.setInputAction((movement: IMovement) => {
                viewer.entities.removeById('pin_marker')

                const cartesian = viewer.camera.pickEllipsoid(
                    movement.position,
                    scene.globe.ellipsoid,
                )
                if (cartesian) {
                    const cartographic =
                        Cesium.Cartographic.fromCartesian(cartesian)
                    const longitudeString = Cesium.Math.toDegrees(
                        cartographic.longitude,
                    )
                    const latitudeString = Cesium.Math.toDegrees(
                        cartographic.latitude,
                    )

                    let lng = lodash.floor(longitudeString, 7)
                    let lat = lodash.floor(latitudeString, 7)

                    emits('update:loc', [lng, lat, 0])
                    buildMarker([lng, lat, 0])
                }
            }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
        })
    } else {
        if (viewer) {
            viewer.destroy()
        }
    }
})
</script>

<style lang="scss" scoped>
.cs-picker {
    height: 600px;
    width: 600px;
}
</style>
<style>
.cesium-viewer-bottom {
    display: none;
    /* top: 200px; */
}

.cesium-widget-credits {
    display: none;
}

.cesium-viewer-toolbar {
    top: 68px;
    left: 435px;
}

.cesium-baseLayerPicker-dropDown {
    z-index: 25;
    top: -4px;
    border-radius: 2px;
}
</style>
